﻿using Microsoft.Phone.Controls;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Navigation;

namespace MvvmCrystalTool
{
    public class MvvmNavigationService : INavigationService
    {
        private class RegItem
        {
            public RegItem(string pageName, object dataContext)
            {
                PageName = pageName;
                DataContext = dataContext;                
            }

            public string PageName { get; private set; }
            public object DataContext { get; set; }
        }

        private static readonly string ViewModelQueryKey = "ViewModelKey";

        private static string _viewsFolder = "";
        public static string ViewsFolder 
        { 
            get 
            { 
                return _viewsFolder; 
            } 
            set
            {
                _viewsFolder = value;
            }
        }

        public MvvmNavigationService(PhoneApplicationFrame rootFrame)
        {
            _rootFrame = rootFrame;
        }

        public void Register(string key, string pageName, object dataContext)
        {
            if (_items.ContainsKey(key))
                throw new ArgumentException("key");

            _items.Add(key, new RegItem(pageName, dataContext));
        }

        public void Navigate(string key)
        {
            var item = _items[key];

            Debug.Assert(item != null);
            if(item == null)
                throw new ArgumentException("key");

            NavigateTo(item.PageName, key);
        }

        public void Navigate(string key, object dataContext)
        {
            RegItem item = _items[key];

            Debug.Assert(item != null);
            if (item == null)
                throw new ArgumentException("key");

            item.DataContext = dataContext;

            NavigateTo(item.PageName, key);
        }

        public object GetDataContext(NavigationContext context)
        {
            if (context == null || context.QueryString == null)
                return null;

            string key;

            if (!context.QueryString.TryGetValue(ViewModelQueryKey, out key))
                return null;

            return _items[key].DataContext;
        }

        private void NavigateTo(string pageName, string key)
        {
            _rootFrame.Navigate(GetPageUri(pageName, key));
        }

        private Uri GetPageUri(string pageName, string key)
        {
            var ns = string.Format("{0}/{1}.xaml?{2}={3}", ViewsFolder, pageName, ViewModelQueryKey, key);

            return new Uri(ns, UriKind.Relative);
        }

        private Dictionary<string, RegItem> _items = new Dictionary<string, RegItem>();
        private PhoneApplicationFrame _rootFrame;
    }
}
